package me.sealer.rpc.dubbo.test;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * @author sealer
 * @date 2018/03/29.
 */
@Slf4j
public class DubboUtil {
    private static final String DUBBO_PROTOCOL_PREFIX = "dubbo://";
    private static final String DEFAULT_SERVICE_VERSION = "0.0.0";
    private static final String DEFAULT_APPLICATION_NAME = "dubbo-test";
    private static final Integer DEFAULT_TIMEOUT = 60000;

    /**
     * @param request        请求bean泛型
     * @param serviceClazz   dubbo接口泛型
     * @param host           dubbo服务注册ip
     * @param port           dubbo服务注册端口
     * @param methodName     dubbo服务调用方法名
     * @param serviceVersion 接口版本号 版本
     * @param groupName      服务的组名
     * @param <Request>
     * @param <Response>
     * @param <Service>
     * @return response 返回bean泛型
     */
    public static <Request, Response, Service> Response testInterface(Request request, Class<Service> serviceClazz, String host, int port, String methodName, String serviceVersion, String groupName, Integer timeout) {
        Method method;
        Response response = null;
        try {
            method = serviceClazz.getMethod(methodName, request.getClass());
            String interfaceFullName = serviceClazz.getName();
            String url = DUBBO_PROTOCOL_PREFIX + host + ":" + port + "/" + interfaceFullName;
            ReferenceBean<Service> referenceBean = new ReferenceBean<>();
            referenceBean.setApplication(new ApplicationConfig(DEFAULT_APPLICATION_NAME));
            referenceBean.setInterface(serviceClazz);
            referenceBean.setUrl(url);
            referenceBean.setVersion(serviceVersion);
            if (timeout == null) {
                timeout = DEFAULT_TIMEOUT;
            }
            referenceBean.setTimeout(timeout);
            if (groupName != null && !"".equals(groupName)) {
                referenceBean.setGroup(groupName);
            }
            referenceBean.afterPropertiesSet();
            Service demoService = referenceBean.get();
            Object objResult = method.invoke(demoService, request);
            if (objResult == null) {
                return null;
            }
            response = (Response) objResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * @param request      请求bean泛型
     * @param serviceClazz dubbo接口泛型
     * @param host         dubbo服务注册ip
     * @param port         dubbo服务注册端口
     * @param methodName   dubbo服务调用方法名
     * @param <Request>
     * @param <Response>
     * @param <Service>
     * @return response 返回bean泛型
     */
    public static <Request, Response, Service> Response testInterface(Request request, Class<Service> serviceClazz, String host, int port, String methodName) {
        return testInterface(request, serviceClazz, host, port, methodName, DEFAULT_SERVICE_VERSION, null, null);
    }

    /**
     * @param request        请求bean泛型
     * @param serviceClazz   dubbo接口泛型
     * @param host           dubbo服务注册ip
     * @param port           dubbo服务注册端口
     * @param methodName     dubbo服务调用方法名
     * @param serviceVersion 服务版本号
     * @param <Request>
     * @param <Response>
     * @param <Service>
     * @return response 返回bean泛型
     */
    public static <Request, Response, Service> Response testInterface(Request request, Class<Service> serviceClazz, String host, int port, String methodName, String serviceVersion) {
        return testInterface(request, serviceClazz, host, port, methodName, serviceVersion, null, null);
    }

    public static <Request, Response, Service> Response testInterface(Request request, Class<Service> serviceClazz, String host, int port, String methodName, Integer timeout) {
        return testInterface(request, serviceClazz, host, port, methodName, DEFAULT_SERVICE_VERSION, null, timeout);
    }
}
